package com.fourhats.dao.impl;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.fourhats.dao.ProductDAO;
import com.fourhats.model.Product;

@Repository
public class ProductDAOImpl extends GenericDAOImpl<Product, Long> implements ProductDAO {

	protected ProductDAOImpl() {
		super(Product.class.getName());
	}

	@SuppressWarnings("unchecked")
	public List<Product> getProductsByKeyword(String keyWord) {
		DetachedCriteria criteria = this.GetProducts();
        criteria.add(Restrictions.ilike("name", keyWord, MatchMode.ANYWHERE));
        criteria.addOrder(Order.asc("name"));
        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        return getHibernateTemplate().findByCriteria(criteria);
	}

	@SuppressWarnings("unchecked")
	public List<Product> getRandomlyHighlightProducts(int maxResult) {
		DetachedCriteria criteria = this.GetProducts();
		criteria.add(Restrictions.eq("highlight", true));
        criteria.addOrder(Order.asc("name"));
        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        List<Product> products = getHibernateTemplate().findByCriteria(criteria, 0, maxResult*5);
        java.util.Collections.shuffle(products);
        maxResult = maxResult < products.size() ? maxResult : products.size();
        return products.subList(0, maxResult);
	}

	@SuppressWarnings("unchecked")
	public List<Product> getProductsByCategory(long categoryId) {
		DetachedCriteria criteria = this.GetProducts();
        criteria.add(Restrictions.eq("category.id", categoryId));
        criteria.addOrder(Order.asc("name"));
        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        return getHibernateTemplate().findByCriteria(criteria);
	}
	
	@SuppressWarnings("unchecked")
	public List<Product> getProductsByEnabledMarket(long marketId) {
		DetachedCriteria criteria = this.GetProducts();
        criteria.add(Restrictions.eq("market.id", marketId));
        criteria.addOrder(Order.asc("name"));
        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        return getHibernateTemplate().findByCriteria(criteria);
	}
	
	@SuppressWarnings("unchecked")
	public List<Product> getProductsByMarket(long marketId) {
		DetachedCriteria criteria = this.getEnabledProducts();
        criteria.add(Restrictions.eq("market.id", marketId));
        criteria.addOrder(Order.asc("name"));
        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        return getHibernateTemplate().findByCriteria(criteria);
	}
	
	@SuppressWarnings("unchecked")
	public List<Product> getAllProducts() {
		DetachedCriteria criteria = GetProducts();
        criteria.addOrder(Order.asc("name"));
        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        return getHibernateTemplate().findByCriteria(criteria);
	}
	
	private DetachedCriteria GetProducts() {
		DetachedCriteria criteria = DetachedCriteria.forEntityName(entityName);
		criteria.createCriteria("market", "market");
		criteria.add(Restrictions.eq("enable", true));
        criteria.add(Restrictions.eq("market.enable", true));
		return criteria;
	}
	
	private DetachedCriteria getEnabledProducts() {
		DetachedCriteria criteria = DetachedCriteria.forEntityName(entityName);
		criteria.createCriteria("market", "market");
		criteria.add(Restrictions.eq("enable", true));
		return criteria;
	}
}